home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 2.iso
/
STUTTGART
/
TEX-UTIL
/
DVI_DVI1
/
dvilj
/
c
/
dviIO
< prev
next >
Wrap
Text File
|
1996-02-20
|
19KB
|
660 lines
#include "dvilj.h"
/* The following functions buffer input/output during CopyFile / CopyHPFile
Write functions are only needed if RISC_BUFFER is defined; otherwise output
is not buffered. */
/* read a buffered byte */
char b_read(FILEPTR spfp)
{
if (biact >= binumber)
{
#ifdef RISC_USE_OSL
binumber = BUFFSIZE - read_multi(buffin,1,BUFFSIZE,spfp);
#else
binumber = read_multi(buffin,1,BUFFSIZE,spfp);
#endif
biact = 0;
}
if (binumber == 0) {return(0);} else {return(buffin[biact++]);}
}
#ifdef RISC_BUFFER
/* write a buffered byte */
void b_write(FILEPTR spfp, char c)
{
if (boact >= BUFFSIZE)
{
write_multi(buffout,1,BUFFSIZE,spfp);
boact = 0;
}
buffout[boact++] = c;
}
/* write a sequence of bytes to the output buffer */
void b_wrtmult(FILEPTR spfp, char *buf, int len)
{
register int i;
if ((len > (BUFFSIZE - boact)) || (len >= (BUFFSIZE/4)))
{
write_multi(buffout,1,boact,spfp);
/* Copy only small blocks; large ones are written directly */
if (len < (BUFFSIZE/4)) {for (i=0; i<len; i++) {buffout[i] = buf[i];} boact = len;}
else {write_multi(buf,1,len,spfp); boact = 0;}
}
else {for (i=0; i<len; i++) {buffout[boact++] = buf[i];}}
}
/* flush the output buffer */
void b_oflush(FILEPTR spfp)
{
write_multi(buffout,1,boact,spfp);
boact = 0;
}
#endif
/* end of buffer handling functions */
/*-->CopyFile*/ /* copy a file straight through to output */
/*********************************************************************/
/***************************** CopyFile ******************************/
/*********************************************************************/
void
CopyFile(char *str )
{
FILEPTR spfp;
char t;
int todo;
/*printf("CopyFile...\n");*/
if ((spfp = BINOPEN(str)) == FPNULL) {
Warning("Unable to open file %s", str );
return;
}
qfprintf(ERR_STREAM," [%s", str);
#ifdef RISC_BUFFER
b_oflush(outfp);
#endif
/* Let's speed things up a little
for (read_byte(spfp,(char)t); !FEOF(spfp); read_byte(spfp,(char)t))
write_byte(outfp,t);*/
do
{
todo = read_multi(buffin,1,BUFFSIZE,spfp);
write_multi(buffin,1,todo,outfp);
}
while (todo == BUFFSIZE);
BCLOSE(spfp);
qfprintf(ERR_STREAM,"]");
}
/*-->CopyHPFile*/ /* copy a HP file to output removing unwanted control codes*/
/*********************************************************************/
/***************************** CopyHPFile ******************************/
/*********************************************************************/
void
CopyHPFile(char *str )
{
FILEPTR spfp;
char t,numstr[20];
int count,rx,ry,miny,minx,num;
/*printf("CopyHPFile...\n");*/
if ( (spfp = BINOPEN(str)) == FPNULL ) {
Warning("Unable to open file %s", str );
return;
}
minx=32767; /* Set to a high value initially */
miny=32767;
/* Pass through the input PCL file twice. The first time find the smallest */
/* x- and y-offsets so that they can be subtracted out when sending */
/* positioning commands later. The second pass strips the unwanted commands */
/* from the input file and outputs the rest */
/* reset the input buffer */
binumber=0; biact=0;
qfprintf(ERR_STREAM," [%s", str);
/* Test for !EOF now ((binumber == BUFFSIZE) || (biact < binumber)) */
do
{
t = (char)b_read(spfp);
if (t==0x1B) /* Find the escape character */
{
t = (char)b_read(spfp);
if (t==0x2A) /* This indiactes the start of a graphics command */
{
t = (char)b_read(spfp);
switch(t)
{
case(0x70):
/* These are the graphics positioning commands */
/* Find the smallest x and y offsets */
num=0;
count=0;
for (t = (char)b_read(spfp); t<0x40; t = (char)b_read(spfp))
numstr[count++]=t;
numstr[count]=0;
num= atoi (numstr);
/* Take into account the possible different ordering */
/* of the commands (x first, y first) */
if ((t==0x59)||(t==0x79))
{
if (numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
if (num<miny) miny=num;
if (t==0x79)
{
num=0;
count=0;
for (t = (char)b_read(spfp); t<0x40; t = (char)b_read(spfp))
numstr[count++]=t;
numstr[count]=0;
num=atoi (numstr);
if(numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
if (num<minx) minx=num;
}
}
if ((t==0x58)||(t==0x78))
{
if (numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
if (num<minx) minx=num;
if (t==0x78)
{
num=0;
count=0;
for (t = (char)b_read(spfp); t<0x40; t = (char)b_read(spfp))
numstr[count++]=t;
numstr[count]=0;
num= atoi (numstr);
if (numstr[0]!='+'&&numstr[0]!='-'&&numstr[0]!='-')
if (num<miny) miny=num;
}
}
break;
/* Ignore all other commands for the moment - just read them */
case(0x74):
for (t = (char)b_read(spfp); t != 0x52; t = (char)b_read(spfp));
break;
case(0x72):
for (t = (char)b_read(spfp); ((t< 0x40)||(t>0x60)); t = (char)b_read(spfp));
break;
case(0x62):
num=0;
count=0;
/* Read in the correct number of bytes of raster graphics */
/* so that we don't get commands and raster graphics confused */
for (t = (char)b_read(spfp); ((t<0x40)||(t>=0x60)); t = (char)b_read(spfp))
numstr[count++]=t;
numstr[count]=0;
if (t==0x4D)
for(t=numstr[count=0];t!=0;t=numstr[++count]);
if (t==0x57)
{
for(t=numstr[count=0];t!=0;t=numstr[++count]);
for(count= atoi(numstr);count>0;count--)
t = (char)b_read(spfp);
}
break;
case(0x63):
for (t = (char)b_read(spfp); ((t< 0x40)||(t>0x60)); t = (char)b_read(spfp));
break;
default:
break;
}
}
}
}
while ((binumber == BUFFSIZE) || (biact < binumber));
BCLOSE(spfp);
qfprintf(ERR_STREAM,"]");
if ( (spfp = BINOPEN(str)) == FPNULL ) {
Warning("Unable to open file %s", str );
return;
}
qfprintf(ERR_STREAM," [%s", str);
/* reset input buffer again */
binumber = 0; biact = 0;
/* Pass through the input file again but this time output the */
/* retained PCL commands */
/* Remark: I changed all instances of fputc (or rather write_byte) with EMITC to make the
whole thing somewhat more consistent. */
do
{
t = (char)b_read(spfp);
if (t==0x1B)
{
t = (char)b_read(spfp);
if (t==0x2A)
{
t = (char)b_read(spfp);
switch(t)
{
case(0x70):
num=0;
count=0;
for (t = (char)b_read(spfp); t<0x40; t = (char)b_read(spfp))
numstr[count++]=t;
numstr[count]=0;
num= atoi (numstr);
if ((t==0x59)||(t==0x79))
{
if (numstr[0]!='+'&&numstr[0]!='-')
{
/* Subtract the minimum offset found in first pass */
/* and add in the current vertical offset */
ry=num-miny+(int)PIXROUND(v,vconv)+y_goffset;
/* Output the new positioning command */
EMIT(EMTO,"\033*p%dY",ry); EMFLUSH;
}
else if (num>=0) {EMIT(EMTO,"\033*p%c%dY",numstr[0],num); EMFLUSH;}
else {EMIT(EMTO,"\033*p%dY",num); EMFLUSH;}
if (t==0x79)
{
num=0;
count=0;
for (t = (char)b_read(spfp); t<0x40; t = (char)b_read(spfp))
numstr[count++]=t; /* reconstructed code */
numstr[count]=0;
num=atoi (numstr);
if(numstr[0]!='+'&&numstr[0]!='-')
{
/*Add in correct horizontal offset */
rx=num-minx+(int)PIXROUND(h,hconv)+x_goffset;
EMIT(EMTO,"\033*p%dX",rx); EMFLUSH;
}
else if (num>=0) {EMIT(EMTO,"\033*p%c%dX",numstr[0],num); EMFLUSH;}
else {EMIT(EMTO,"\033*p%dX",num); EMFLUSH;}
}
}
if ((t==0x58)||(t==0x78))
{
if(numstr[0]!='+'&&numstr[0]!='-')
{
/*Add in the correct horizontal offset*/
rx=num-minx+(int)PIXROUND(h,hconv)+x_goffset;
EMIT(EMTO,"\033*p%dX",rx); EMFLUSH;
}
else if (num>=0) {EMIT(EMTO,"\033*p%c%dX",numstr[0],num); EMFLUSH;}
else {EMIT(EMTO,"\033*p%dX",num); EMFLUSH;}
if (t==0x78)
{
num=0;
count=0;
for (t = (char)b_read(spfp); t<0x40; t = (char)b_read(spfp))
numstr[count++]=t;
numstr[count]=0;
num= atoi (numstr);
if(numstr[0]!='+'&&numstr[0]!='-')
{
/*Add in correct vertical offset*/
ry=num-miny+(int)PIXROUND(v,vconv)+y_goffset;
EMIT(EMTO,"\033*p%dY",ry); EMFLUSH;
}
else if (num >=0) {EMIT(EMTO,"\033*p%c%dY",numstr[0],num); EMFLUSH;}
else {EMIT(EMTO,"\033*p%dY",num); EMFLUSH;}
}
}
break;
case(0x74):
/* Set the Raster resolution */
EMIT(EMTO,"\033*t"); EMFLUSH;
for (t = (char)b_read(spfp); t != 0x52; t = (char)b_read(spfp))
EMITC(t);
EMITC(t);
break;
case(0x72):
/* Raster Graphics commands such as start */
EMIT(EMTO,"\033*r"); EMFLUSH;
for (t = (char)b_read(spfp); ((t< 0x40)||(t>0x60)); t = (char)b_read(spfp))
EMITC(t);
EMITC(t);
break;
case(0x62):
/* Transfer the correct number of bytes of raster graphics */
EMIT(EMTO,"\033*b"); EMFLUSH;
num=0;
count=0;
for (t = (char)b_read(spfp); ((t<0x40)||(t>=0x60)); t = (char)b_read(spfp))
numstr[count++]=t;
numstr[count]=0;
if (t==0x4D)
{
for(t=numstr[count=0];t!=0;t=numstr[++count])
EMITC(t);
EMIT(EMTO,"M"); EMFLUSH;
}
if (t==0x57)
{
for(t=numstr[count=0];t!=0;t=numstr[++count])
EMITC(t);
EMIT(EMTO,"W"); EMFLUSH;
for(count= atoi(numstr);count>0;count--)
{
t = (char)b_read(spfp);
EMITC(t);
}
}
break;
case(0x63):
/* Rectangular draw commands */
EMIT(EMTO,"\033*c"); EMFLUSH;
for (t = (char)b_read(spfp); ((t< 0x40)||(t>0x60)); t = (char)b_read(spfp))
EMITC(t);
EMITC(t);
break;
default:
break;
}
}
}
}
while ((binumber == BUFFSIZE) || (biact < binumber));
BCLOSE(spfp);
qfprintf(ERR_STREAM,"]");
}
/* This function closes all open files */
void
CloseFiles(void)
{
struct font_entry *fe;
FILEPTR f;
/* First input/output files */
if (outfp != FPNULL) {
#ifdef RISC_BUFFER
b_oflush(outfp);
#endif
BCLOSE(outfp);
}
if (dvifp != FPNULL) {BCLOSE(dvifp);}
if (metafile != FPNULL) {BCLOSE(metafile);}
/* Now all open font files */
fe = hfontptr;
while (fe != NULL)
{
f = fe->font_file_id;
if ((f != FPNULL) && (f != NO_FILE)) {BCLOSE(f);}
fe = fe->next;
}
}
/*-->Fatal*/
/**********************************************************************/
/****************************** Fatal *******************************/
/**********************************************************************/
void
Fatal(fmt, a, b, c) /* issue a fatal error message */
char *fmt;
char *a, *b, *c;
{
fprintf(ERR_STREAM, "\n");
fprintf(ERR_STREAM, "%s: FATAL--", G_progname);
fprintf(ERR_STREAM, fmt, a, b, c);
fprintf(ERR_STREAM, "\n\n");
CloseFiles();
#ifndef vms
exit(2);
#else
exit(SS$_ABORT);
#endif
}
/*-->GetBytes*/
/**********************************************************************/
/***************************** GetBytes *****************************/
/**********************************************************************/
/* get n bytes from file fp; now a macro, so we don't need it any more
void
GetBytes(FILEPTR fp, char *cp, int n)
{
read_multi(cp,n,1,fp);
}*/
/*-->NoSignExtend*/
/**********************************************************************/
/*************************** NoSignExtend ***************************/
/**********************************************************************/
long4
NoSignExtend(FILEPTR fp, register int n) /* return n byte quantity from file fd */
{
long4 x=0; /* number being constructed */
char h;
while (n--) {
x <<= 8; read_byte(fp,h);
x |= h;
}
/* printf("[%x] ",x);*/
return(x);
}
#ifndef ARITHMETIC_RIGHT_SHIFT
long4 signTab[5] = {0,0x00000080,0x00008000,0x00800000,0x00000000};
long4 extendTab[5] = {0,~0^0xff,~0^0xffff,~0^0xffffff,~0^0xffffffff};
#endif
/*-->SignExtend*/
/**********************************************************************/
/**************************** SignExtend ****************************/
/**********************************************************************/
long4
SignExtend(FILEPTR fp, register int n) /* return n byte quantity from file fd */
{
int n1; /* number of bytes */
long4 x; /* number being constructed */
char h;
#ifdef SIGN_DEBUG
long4 x0; /* copy of x */
#endif
read_byte(fp,h); x=h; /* get first (high-order) byte */
n1 = n--;
while (n--) {
x <<= 8; read_byte(fp,h);
x |= h;
}
/*
* NOTE: This code assumes that the right-shift is an arithmetic, rather
* than logical, shift which will propagate the sign bit right. According
* to Kernighan and Ritchie, this is compiler dependent!
*/
/* printf("[%x] ",x);*/
#ifdef SIGN_DEBUG
x0 = x;
#endif
#ifdef ARITHMETIC_RIGHT_SHIFT
x <<= 32 - 8 * n1;
x >>= 32 - 8 * n1; /* sign extend */
#else
if (x & signTab[n1]) x |= extendTab[n1];
#endif
#ifdef SIGN_DEBUG
fprintf(ERR_STREAM,"\tSignExtend(fp,%d)=%lX, was=%lX,%d\n",
n1,x,x0,x0&signTab[n1]);
#endif
#ifdef DEBUG
if (Debug > 1)
fprintf(ERR_STREAM,"\tSignExtend(fp,%d)=%lx\n", n1, x);
#endif
return(x);
}
#ifdef IBM3812
/*-->PMPout*/
/*****************************************************************************/
/* This routine produces the PMP-envelopes for the 3812. Its semantics are:
first arg == 0 ... flush buffer
first arg == -1 ... number of bytes specified in the second argument
have to be continuous, that is they must not
be disrupted by ENTER PMP etc.
first arg > 0 output first arg bytes
If arg2 > OUTBUFSIZE ... flush buffer,
switch to unbuffered mode
(dont't collect PMP commands)
If arg2+bufferpointer > OUTBUFSIZE ... flush buffer,
block will fit into buffer
otherwise ..... block will fit into buffer
Buffering is done to reduce the ENTER PMP-commands. Initially
the 3812 is in PC-ASCII mode. In order to issue a PMP-command it is
necessary to enter PMP mode. The ENTER-PMP-command contains the
number of bytes that will be interpreted as PMP-commands. In the
most naive approach for each primitive command (eg. set cursor) you
have to produce a seperate ENTER-PMP-envelope (5 bytes). It is
favourable to collect as many PMP commands as possible in one envelope. */
/*****************************************************************************/
void
PMPout(int l, char *s)
{
static char buffer[OUTBUFSIZE];
static unsigned short bp = 0; /* range 0..OUTBUFSIZE */
static long4 continuous = 0l;
static bool buffered = _TRUE;
if (l == 0) {
if (bp == 0)
return;
EMIT(EMTO, "\033[C%c%c", (unsigned char)(bp & 0xFF),
(unsigned char)(bp >> 8)); EMFLUSH;
EMITB((int)bp, buffer);
bp = 0;
return;
}
if (l == -1) {
continuous = (long4)s;
if (continuous + (long4)bp + 5l > (long4) OUTBUFSIZE)
PMPflush;
buffered = (bool) ((continuous + 5l <= (long4) OUTBUFSIZE));
if (!buffered) {
EMIT(EMTO, "\033[C%c%c",
(unsigned char)(continuous & 0xFF),
(unsigned char)((continuous >> 8) & 0xFF)); EMFLUSH;
}
return;
}
if (buffered) {
register int i;
if ( ((long4)l + bp) > OUTBUFSIZE)
PMPflush;
for (i = 0; i < l; i++)
buffer[bp+i] = s[i];
bp += (unsigned short)l;
} else {
EMITB((int)l, s);
buffered = (bool) ((continuous -= (long4)l) <= 0) ;
}
}
void
PMPoutC(char c)
{
PMPout(1, &c);
}
#endif
#ifdef MSDOS
/*-->AssureBinary*/
/**********************************************************************/
/*************************** AssureBinary *****************************/
/**********************************************************************/
/* This procedure is both DOS AND MSC dependent. The MSC file open on */
/* a device ignores the 'binary' of the "wb" parameter and opens the */
/* file in ascii mode. This procedure sets the file f to binary mode */
/* if it is connected to a device that is not console input or output */
/* or the null device. For other operating systems this routine is */
/* useless. (Background: MSDOS 3.2 Technical Reference upd 1 pg 6-137 */
/**********************************************************************/
void
AssureBinary(FILEPTR f)
{
union REGS regs; /* registers for bios call */
regs.h.ah = (unsigned char) 0x44; /* IOCTL */
regs.h.al = (unsigned char) 0x00; /* get device information */
regs.x.bx = (unsigned int) fileno(f); /* handle from MSC */
intdos(®s, ®s); /* call DOS interrupt */
/* ---> result in DX */
if ( (regs.h.dl & 0x80) /* file handle points to a device */
&& !(regs.h.dl & 0x07) ) /* neither console i/o or null */ {
regs.h.dl |= 0x20; /* set BINARY bit in device info */
regs.h.ah = (unsigned char) 0x44; /* IOCTL */
regs.h.al = (unsigned char) 0x01; /* set device information*/
regs.x.bx = (unsigned int) fileno(f); /* handle from MSC */
regs.h.dh = (unsigned char) 0x00; /* clear DH */
intdos(®s, ®s); /* call DOS interrupt */
}
}
#endif
/*-->Warning*/
/**********************************************************************/
/***************************** Warning ******************************/
/**********************************************************************/
void /* issue a warning */
Warning(char *fmt, char *a, char *b, char *c, char *d)
{
if ( G_nowarn || G_quiet )
return;
fprintf(ERR_STREAM, "%s: warning: ", G_progname);
fprintf(ERR_STREAM, fmt, a, b, c, d);
fprintf(ERR_STREAM, "\n");
}